#!/usr/bin/env python

## Copyright (C) 2008 Navid Sheikhol-Eslami <navid@navid.it>

### This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.

## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.

## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

from logst.logs_abstraction import *
import re, traceback

class base_Parser_class:

   default_icon = "images/32px-Crystal_Clear_app_ktip.png"

   def __init__(self, cluster, config):

      self.cluster = cluster
      self.global_config = config
      self.regex_callback = []
      self.options = []
      self.enabled = True

      self.stats = {"events":0} 

      if hasattr(self,"initialize"):
         self.initialize()

      if hasattr(self,"init_activators"):
         self.init_activators()

   def is_enabled(self):

      return self.enabled == True

   def is_disabled(self):

      return not self.is_enabled()

   def clear_activators(self):

      self.regex_callback = []

   def reinit_activators(self):

      self.clear_activators()

      if hasattr(self,"init_activators"):
         self.init_activators()

   def get_description(self):

      if hasattr(self, "description"):
         return self.description
      else:
         return ""

   __vars = {}

   def get_variable(self, name, host = None, default = None):

      if not host:
         host = "all"

      try:    return self.__vars[host][name]
      except: pass

      if host != "all":

         try:    return self.__vars["all"][name]
         except: pass

      return default

   def set_variable(self, name, value, host = None):

      if not host:
         host = "all"

      if not self.__vars.has_key(host):
         self.__vars[host] = {}

      self.__vars[host][name] = value

   def add_option(self, opt_id, txt_descr, possible_values = [True, False], default_value = True):

      self.options.append( base_Parser_option_class( "%s~%s" % (self.name(), opt_id), txt_descr, possible_values, default_value) )

   def has_options(self):

      return len(self.options) > 0

   def list_options(self):

      return self.options

   def has_option(self, opt_id):

      return self.get_option(opt_id) != None

   def get_option(self, opt_id):

      for option in self.options:
         if option.uid == "%s~%s" % (self.name(), opt_id):
            return option

      print "cannot find", opt_id, option.uid

      return None

   def get_option_value(self, opt_id):

      return self.get_option(opt_id).get_value()

   def name(self):
      return self.__class__.__name__

   def add_regex_activator(self, regex, line_parser_callback):

      self.regex_callback.append( regex_parser_rule_class(regex, line_parser_callback, enabled = True) )

   def get_regex_rules(self):

      return [ regex_parser.regex for regex_parser in self.regex_callback ]

   def activate_check(self, log):
      for regex_parser in self.regex_callback:

         if regex_parser.regex_c.match(log.line):
            return True
      return False

   def run_parse(self, log):
      for regex_parser in self.regex_callback:
         if regex_parser.regex_c.match(log.line):
            regex_parser.hits += 1
            try:
               regex_parser.parser_callback(log)
            except:
               traceback.print_exc(file=sys.stdout)
               return False
            else:
               return True
      return False

   def add_event(self, log, text, long_text = None, icon = None, groupable = EVENT_ALWAYS_GROUPABLE):

      if not icon and self.default_icon:
         icon = self.default_icon

      self.stats["events"] += 1

      return self.cluster.events.add(text, long_text = long_text, log_lines = [log], icon = icon, groupable = groupable)

   def add_hint(self, regex, hint_txt, pre_regex = "^|[^a-zA-Z0-9]", post_regex = "[^a-zA-Z0-9]|$", hostnames = []):

      self.cluster.hints.add(regex, hint_txt, pre_regex, post_regex, hostnames)

class regex_parser_rule_class:

   def __init__(self, regex, line_parser_callback, enabled = True):

      self.regex = regex
      self.regex_c = re.compile(".*" + regex)
      self.parser_callback = line_parser_callback
      self.enabled = enabled
      self.hits = 0

class base_Parser_option_class:

   true_values = ["on", "yes", True]
   false_values = ["off", "no", False]

   def __init__(self, option_id, description, possible_values, default_value):

      self.uid = option_id
      self.description = description
      self.possible_values = possible_values
      self.set_value(default_value)

   def get_value(self):

      return self.value

   def set_value(self, value):

      if value in self.true_values:
         value = True
      elif value in self.false_values:
         value = False

      if hasattr(self, "value") and self.value == value:
         return

      if value not in self.possible_values:
         print "value invalid", value, self.possible_values
         raise "Invalid_Value"

      self.value = value

   def is_boolean(self):

      for value in self.possible_values:
         if value not in self.true_values and value not in self.false_values:
            return False

      return True

   def is_true(self):

      return self.value in self.true_values

   def is_false(self):

      return self.value in self.false_values
